package com.knowledge.graph.service.impl;

import com.knowledge.graph.mapper.CourseMapper;
import com.knowledge.graph.mapper.GradeAndCourseMapper;
import com.knowledge.graph.mapper.GradeAndUserMapper;
import com.knowledge.graph.mapper.GradeMapper;
import com.knowledge.graph.model.entity.*;
import com.knowledge.graph.model.vo.CourseVO;
import com.knowledge.graph.service.GradeService;
import com.knowledge.graph.model.vo.ResponseVO;
import com.knowledge.graph.model.vo.StatusCode;
import com.knowledge.graph.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

@Service
public class GradeServiceImpl implements GradeService {

    @Autowired
    private GradeMapper gradeMapper;

    @Resource
    private GradeAndUserMapper gradeAndUserMapper;

    @Resource
    private GradeAndCourseMapper gradeAndCourseMapper;

    @Resource
    private CourseMapper courseMapper;

    @Override
    public ResponseVO createGrade(String name, String description, Integer teacherID) {
        Grade grade = new Grade(name, description, teacherID);
        int flag = gradeMapper.insertGrade(grade);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), grade);
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO modifyGrade(Integer gradeID, String name, String description) {
        Grade grade = new Grade(gradeID, name, description);
        int flag = gradeMapper.updateById(grade);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO removeGrade(Integer gradeID) {
        int flag = gradeMapper.deleteById(gradeID);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO queryGrade(Integer teacherID) {
        List<Grade> grades = gradeMapper.selectByTeacherID(teacherID);
        if (grades != null)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), grades);
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO modifyGradeOfCourse(Integer gradeID, Integer courseID) {
        Grade grade = new Grade(gradeID, courseID);
        int flag = gradeMapper.updateById(grade);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO modifyGradeOfInvitationCode(Integer gradeID) {
        String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        Random random = new Random();
        StringBuffer invitationCode = new StringBuffer();
        for (int i = 0; i < 8; i++) {
            int number = random.nextInt(62);
            invitationCode.append(str.charAt(number));
        }
        Grade grade = new Grade(gradeID, invitationCode.toString());
        int flag = gradeMapper.updateById(grade);
        if (flag == 1)
            return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), grade.getInvitationCode());
        return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
    }

    @Override
    public ResponseVO createGradeAndCourse(Long gradeId, Long courseId) {
        GradeAndCourse gradeAndCourse = new GradeAndCourse();
        gradeAndCourse.setCourseId(courseId);
        gradeAndCourse.setGradeId(gradeId);
        int flag = gradeAndCourseMapper.insert(gradeAndCourse);
        if (flag != 1) {
            return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
        }
        return new ResponseVO<>(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
    }

    @Override
    public ResponseVO queryClassByUser(Long userId) throws IOException {
        Long queryGradeId = gradeAndUserMapper.selectByUserId(userId);
        if (queryGradeId == 0) {
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_SELECT.getMessage());
        }
        List<Long> queryCourseIds = gradeAndCourseMapper.selectByGradeId(queryGradeId);
        List<CourseVO> courseVOList = new ArrayList<>();
        for (Long queryCourseId : queryCourseIds) {
            Course course = courseMapper.selectById(queryCourseId);
            String imageToBase64 = FileUtils.ImageToBase64(course.getCourseImage());
            CourseVO courseVO = new CourseVO(course, imageToBase64);
            courseVOList.add(courseVO);
        }
        return new ResponseVO(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage(), courseVOList);
    }

    @Override
    public ResponseVO createGradeAndUser(String text, User user) {
        if (text.isEmpty())
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_DELETE.getMessage());
        Long gradeId = gradeMapper.selectByCode(text);
        if (gradeId == null)
            return new ResponseVO(StatusCode.FAIL_SELECT.getCode(), StatusCode.FAIL_DELETE.getMessage());
        GradeAndUser gradeAndUser = new GradeAndUser();
        gradeAndUser.setUserId(user.getId());
        gradeAndUser.setGradeId(gradeId);
        int count = gradeAndUserMapper.selectByGU(gradeAndUser);
        if (count == 1)
            return new ResponseVO(StatusCode.FAIL_ADD.getCode(), StatusCode.FAIL_ADD.getMessage());
        gradeAndUserMapper.insert(gradeAndUser);
        return new ResponseVO<>(StatusCode.SUCCESS.getCode(), StatusCode.SUCCESS.getMessage());
    }

}
